package com.security.config.mobile;

import com.security.config.filter.SecurityFailureHandler;
import com.security.utils.CaptchaUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

@Slf4j
@Component("mobileCodeFilter")
public class MobileCodeFilter extends OncePerRequestFilter {

    @Resource
    SecurityFailureHandler failureHandler;

    @Override
    protected void doFilterInternal
            (HttpServletRequest req, HttpServletResponse res, FilterChain fc)
            throws ServletException, IOException {
        //1.如果是登录请求，则校验 验证码是否正确
        if(StringUtils.equals("/security/mobileLogin",req.getRequestURI()) && StringUtils.equalsIgnoreCase(req.getMethod(),"post")){
            log.info("请求地址===URI==="+req.getRequestURI()+" 请求方式===Method==="+req.getMethod());
            // 获取 httpsession 获取 验证码
            ServletWebRequest servletWebRequest = new ServletWebRequest(req);
            HttpSession session = servletWebRequest.getRequest().getSession();
            MobileCode smsCode = (MobileCode)session.getAttribute(CaptchaUtils.CAPTCHA_MOBILE_KEY);
            //获取 请求 携带的 验证码
            String requestInputMobile = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(),"mobile");
            String requestInputCaptcha = ServletRequestUtils.getStringParameter(servletWebRequest.getRequest(),"captcha");
            System.out.println("session-mobile:"+smsCode.getMobile()+"requestInputMobile:"+requestInputMobile);
            System.out.println("session-Captcha:"+smsCode.getCode()+"requestInputMobile:"+requestInputCaptcha);
            try{
                if(StringUtils.isEmpty(requestInputMobile)){
                    throw new SessionAuthenticationException("手机号码不能为空");
                }
                // 判断请求是否携带 验证码
                if (StringUtils.isEmpty(requestInputCaptcha)){
                    throw new SessionAuthenticationException("验证码不能为空");
                }

                if(Objects.isNull(smsCode)) {
                    throw new SessionAuthenticationException("验证码不存在");
                }

                // 判断 验证码 是否正确
                if (!StringUtils.equalsIgnoreCase(smsCode.getCode(),requestInputCaptcha)){
                    throw new SessionAuthenticationException("验证码不正确");
                }

                if(!smsCode.getMobile().equals(requestInputMobile)) {
                    throw new SessionAuthenticationException("短信发送目标与您输入的手机号不一致");
                }

                // 校验服务器session池中的验证码是否过期
                if (smsCode.isExpired()){
                    throw new SessionAuthenticationException("验证码已经过期");
                }

            }catch (AuthenticationException e){
                session.removeAttribute(CaptchaUtils.CAPTCHA_MOBILE_KEY);
                failureHandler.onAuthenticationFailure(req,res,e);
                return;
            }
            session.removeAttribute(CaptchaUtils.CAPTCHA_MOBILE_KEY);
            //如果匹配继续执行 过滤链
            fc.doFilter(req,res);
        }else {
            fc.doFilter(req,res);
        }


    }
}
